import { CONVERT_TYPE } from "../convertable/Consts"

export class BaseUtil {
  constructor() {
    this.excludeKeys = []
    this.excludeTypeKeys = []
    this.type = CONVERT_TYPE.N
  }

  /**
   *
   * @param {CONVERT_TYPE} type
   * @returns {ParamUtil | ObjectArray}
   */
  setType(type) {
    this.type = type
    return this
  }

  /**
   *
   * @param {String} key
   * @param {String} sep
   * @param {Number} from
   * @param {Number} to
   */
  excludeRangeKeys(key = "ext", sep = "", from = 1, to = 15) {
    const _keys = []
    for (let i = from; i <= to; i++) {
      _keys.push(`${key}${sep}${i}`)
    }

    this.excludeKey(_keys)
  }

  /**
   * @param {Array} keys
   * @returns {ParamUtil | ObjectArray}
   */
  excludeKey(keys = []) {
    this.excludeKeys = this.excludeKeys.concat(keys)
    return this
  }

  /**
   * @param {Array} keys
   * @returns {ParamUtil | ObjectArray}
   */
  excludeTypeKey(keys = []) {
    this.excludeTypeKeys = this.excludeTypeKeys.concat(keys)
    return this
  }

  camel2sneak(str, upper) {
    if (!str) return ""

    return String(str)
      .replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, "")
      .replace(/([a-z])([A-Z])/g, (m, a, b) => a + "_" + b.toLowerCase())
      .replace(/[^A-Za-z0-9]+|_+/g, "_")
      .toLowerCase()
  }

  toCamelCase(str = "") {
    if (!str) return ""

    return String(str)
      .replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, "")
      .replace(/[^A-Za-z0-9]+/g, "$")
      .replace(/([a-z])([A-Z])/g, (m, a, b) => `${a}$${b}`)
      .toLowerCase()
      .replace(/(\$)(\w)/g, (m, a, b) => b.toUpperCase())
  }

  _toTypedKey(key) {
    let typedKey = ""
    if (this.type === CONVERT_TYPE.C) {
      typedKey = this.toCamelCase(key)
    } else if (this.type === CONVERT_TYPE.S) {
      typedKey = this.camel2sneak(key)
    }

    return typedKey
  }
}
